/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 bitset_io.h

	$Header: /heroes4/bitset_io.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( BITSET_IO_H_INCLUDED )
#define BITSET_IO_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <algorithm>
#include <cstdlib>
#include <bitset>
#include <limits>
#include <streambuf>

#include "streambuf_operators.h"

// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
template < size_t k_bit_count >
void put_bitset( std::streambuf & stream, std::bitset< k_bit_count > const & bitset )
{
	int const k_bits_per_char = std::numeric_limits< unsigned char >::digits;
	int const k_buffer_size = ( k_bit_count + k_bits_per_char - 1 ) / k_bits_per_char;

	unsigned char buffer[ k_buffer_size ];
	std::fill_n( &buffer[ 0 ], k_buffer_size, 0 );

	size_t index;
	for ( index = 0; index < k_bit_count; ++index )
	{
		if ( bitset[ index ] )
			buffer[ index / k_bits_per_char ] |= ( 1 << ( index % k_bits_per_char ) );
	}

	if ( write( stream, buffer, sizeof( buffer ) ) != sizeof( buffer ) )
		throw t_streambuf_write_failure();
}

// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
template < size_t k_bit_count >
std::bitset< k_bit_count > get_bitset( std::streambuf & stream )
{
	int const k_bits_per_char = std::numeric_limits< unsigned char >::digits;
	int const k_buffer_size = ( k_bit_count + k_bits_per_char - 1 ) / k_bits_per_char;

	unsigned char buffer[ k_buffer_size ];

	if ( read( stream, buffer, sizeof( buffer ) ) != sizeof( buffer ) )
		throw t_streambuf_read_failure();

	std::bitset< k_bit_count > result;
	size_t index;
	for ( index = 0; index < k_bit_count; ++index )
	{
		if ( ( buffer[ index / k_bits_per_char ] & ( 1 << ( index % k_bits_per_char ) ) ) != 0 )
			result[ index ] = true;
	}

	return result;
}

#endif //!defined( BITSET_IO_H_INCLUDED )
